package dataextraction;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;

import searchstring.QuestaoPesquisa;
import searchstring.StringBuscaLoader;
import searchstring.TokenStringBusca;
import util.ConfigurationBean;


public class EntriesEnginesLoader {


	private HashMap<String,  IntfEngineLoader> CSV_ENGINES;

	private static EntriesEnginesLoader instance;

	private EntriesEnginesLoader() {
		CSV_ENGINES = new LinkedHashMap<String, IntfEngineLoader>();


		CSV_ENGINES.put("IEEE\\All_papers\\csv\\", IEEEEngineLoader.getInstance());
		CSV_ENGINES.put("ACM\\All_papers\\csv\\", ACMEngineLoader.getInstance());
		CSV_ENGINES.put("ISI\\All_papers\\csv\\", ISIEngineLoader.getInstance());
		CSV_ENGINES.put("Science Direct\\All_papers\\csv\\", ScienceDirectEngineLoader.getInstance());
		CSV_ENGINES.put("Scopus\\All_papers\\csv\\", ScopusEngineLoader.getInstance());
//		CSV_ENGINES.put("Springer Link\\All_papers\\csv\\", SpringerLinkEngineLoader.getInstance());
	}

	public static EntriesEnginesLoader getInstance() {
		if (EntriesEnginesLoader.instance == null) {
			EntriesEnginesLoader.instance = new EntriesEnginesLoader();
		}
		return EntriesEnginesLoader.instance;
	}


	public List<Entry> getAllEntriesFromCSV(){

		int duplicados = 0;
		List<Entry> allEntries = new ArrayList<Entry>();

		for(String source_path : CSV_ENGINES.keySet()){
			List<Entry> allEntriesByEngine = new ArrayList<Entry>();

			System.out.println(source_path+" >>>>>>>>>>>>>>>>");
			File enginePath = new File(ConfigurationBean.getInstance().get(ConfigurationBean.DATA_EXTRACTION_ROOT_PATH_KEY).concat(source_path));
			System.out.println(enginePath.exists());
			File[] files = enginePath.listFiles();

			for(File f : files){
				List<Entry> entriesOnfile = new ArrayList<Entry>();
				try {
					entriesOnfile = CSV_ENGINES.get(source_path).reader(f);
				} catch (IOException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				for(Entry entry : entriesOnfile){
					entry.setDocumentTitleTagged(entry.getDocumentTitle());
					entry.setPublicationAbstractTagged(entry.getPublicationAbstract());

					processPreCriteria(entry);
					allEntriesByEngine.add(entry);
				}
			}
			
			System.out.println();
			this.sortCollectionEntries(allEntriesByEngine);
			allEntries.addAll(allEntriesByEngine);
		}

		List<Entry> uniqueEntries = new ArrayList<Entry>();
		
		//Identificando duplicados
		for(Entry entry : allEntries){
			if(uniqueEntries.indexOf(entry) != -1){
				//System.err.println("Entrada duplicada: "+entry.getDocumentTitle());
				duplicados++;
				entry.getPreCriteria().add("DUPLICADO");
				entry.getPreCriteria().add(uniqueEntries.get(uniqueEntries.indexOf(entry)).getId());
			}
			uniqueEntries.add(entry);
		}

		System.out.println("# de ENTRADAS DUPLICADAS: "+duplicados);
		System.out.println("# de ENTRADAS ADD MANUAL: "+AbstractEngineLoader.NUM_OF_ADD_MANUAL);

		return allEntries;
	}

	private void sortCollectionEntries(List<Entry> entriesOnFile) {

		Collections.sort(entriesOnFile);
		int indexEntry = 1;
		for (Entry entry : entriesOnFile) {
			entry.setId("A_"+entry.getPublisher()+"_"+indexEntry++);
		}
	}

	private void processPreCriteria(Entry entry) {
		Boolean decorarPalavraChave = Boolean.valueOf(ConfigurationBean.getInstance().get(ConfigurationBean.DECORAR_PALAVRAS_CHAVES_KEY));
		String[] criteriaColors = {"red","green","blue","orange","pink","purple","gray"};

		Set<String> setTermosDestacadosTitulo = new HashSet<String>();
		Set<String> setTermosDestacadosAbstract = new HashSet<String>();

		int indexColor = 0;
		for (QuestaoPesquisa questaoPesquisa : StringBuscaLoader.getInstance().getQuestoesPesquisa()) {
			String rq = questaoPesquisa.getName();
			boolean allTokensAreUsed = true;
			Set<String> setTermosDestacadosTituloByToken = new HashSet<String>();
			Set<String> setTermosDestacadosAbstractByToken = new HashSet<String>();
			for (TokenStringBusca tokenStringBusca : questaoPesquisa.getTokensStringBusca()) {
				boolean hasSynonym = false;
				for (String term : tokenStringBusca.getSinonimos()) {

					String termToBeChecked = null;

					if(term.contains("*")){
						termToBeChecked = " " + term.replace("*", "");
					}else{
						termToBeChecked = " " + term;
					}

					termToBeChecked = termToBeChecked.replace("\"", "").replace("'", "");


					if(StringUtils.containsIgnoreCase(entry.getPublicationAbstract(), termToBeChecked)){
						hasSynonym = true;
						setTermosDestacadosAbstractByToken.add(termToBeChecked);
					}

					if(StringUtils.containsIgnoreCase(entry.getDocumentTitle(), termToBeChecked)){
						hasSynonym = true;
						setTermosDestacadosTituloByToken.add(termToBeChecked);
					}

				}

				if(!hasSynonym){
					allTokensAreUsed = false;
					break;
				}
			}
			if(allTokensAreUsed){
				for (String term : setTermosDestacadosAbstractByToken) {
					/*String regex = ".*[<].+[>][$]sb[$](^([$]sb[$]))*"+term+"(^([$]eb[$]))*[$]eb[$]"+"[<][\\\\].+[>].*";*/

					if(decorarPalavraChave){
						if(!setTermosDestacadosAbstract.contains(term) /*&& !this.validateByRegex(regex,  entry.getPublicationAbstract())*/){
							int indexTerm = StringUtils.indexOfIgnoreCase(entry.getPublicationAbstractTagged(), term);
							int lengthTerm = term.length();

							String abstractDocument =  entry.getPublicationAbstractTagged().substring(0, indexTerm + 1) +
							"<"+criteriaColors[indexColor]+">"+"$sb$"
							+ term.toUpperCase() + 
							"$eb$"+"<\\"+criteriaColors[indexColor]+">"
							+ entry.getPublicationAbstractTagged().substring(indexTerm + lengthTerm);

							entry.setPublicationAbstractTagged(abstractDocument);
						}

						entry.getPreCriteria().add("<"+criteriaColors[indexColor]+">"+"$sb$"+rq+"$eb$"+"<\\"+criteriaColors[indexColor]+">");						
					}else{
						entry.getPreCriteria().add(rq);
					}

					setTermosDestacadosAbstract.add(term);
				}

				for (String term : setTermosDestacadosTituloByToken) {
					if(decorarPalavraChave){
						if(!setTermosDestacadosTitulo.contains(term)){
							int indexTerm = StringUtils.indexOfIgnoreCase(entry.getDocumentTitleTagged(), term);
							int lengthTerm = term.length();

							String title =  entry.getDocumentTitleTagged().substring(0, indexTerm + 1) +
							"<"+criteriaColors[indexColor]+">"+"$sb$"
							+ term.toUpperCase() + 
							"$eb$"+"<\\"+criteriaColors[indexColor]+">"
							+ entry.getDocumentTitleTagged().substring(indexTerm + lengthTerm);

							entry.setDocumentTitleTagged(title);
						}

						entry.getPreCriteria().add("<"+criteriaColors[indexColor]+">"+"$sb$"+rq+"$eb$"+"<\\"+criteriaColors[indexColor]+">");
					}else{
						entry.getPreCriteria().add(rq);
					}
					setTermosDestacadosTitulo.add(term);
				}
			}

			indexColor++;
		}
		//		System.out.println(entry.getId() + "\t" + entry.getPreCriteria());

	}

	public Boolean validateByRegex(String regex,String value){
		Pattern p = Pattern.compile(regex);
		Matcher m = p.matcher(value);
		boolean isValid = m.matches();
		return isValid;
	}
}
